/**
 * @file	halPeripheral.c
 * @author	chipsea
 * @brief	
 * @version	0.1
 * @date	2020-11-30
 * @copyright Copyright (c) 2020, CHIPSEA Co., Ltd.
 * @note
 */

/*********************************************************************
 * INCLUDES
 */
#include "log.h"
#include "key.h"
#include "spi.h"
#include "dma.h"
#include "OSAL.h"
#include "gpio.h"
#include "clock.h"
#include "error.h"
#include <stdio.h>
#include "pwrmgr.h"
#include "rom_sym_def.h"
#include "global_config.h"
#include "halPeripheral.h"


#define SPI_MASTER


uint8 Hal_TaskID;

/**
* @fn int str2int(const char *str)
* @brief change string type data to int type data
* @param str: input string type data
* @return output int type data.
*/
int str2int(const char *str)
{
	int temp = 0;
	const char *ptr = str;
	if (*str == '-' || *str == '+')
	{
		str++;
	}
	while (*str != 0)
	{
		if ((*str < '0') || (*str > '9'))
		{
			break;
		}
		temp = temp * 10 + (*str - '0');
		str++;
	}
	if (*ptr == '-')
	{
		temp = -temp;
	}
	return temp;
}

char    *slaveTxBuf = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ+-*@";
uint32_t slaveTxLen = 0;

uint8_t  slaveRxBuf[64] = {0};
uint32_t slaveRxLen = 0;
uint32_t slaveRxNum = 0;
uint8_t slaveRxEnable = 0;


void dma_cb(DMA_CH_t ch)
{
	LOG("dma done\r\n");
}

HAL_DMA_t dma_cfg =
{
    .dma_channel = SPI_DMAC_CH,
    .evt_handler = dma_cb,
};

/**
* @fn void UserSpiHandle(spi_evt_t *pevt)
* @brief spi slave recvice callback function.
* @param pevt:  spi transfer data
* @return NONE.
*/
void UserSpiHandle(spi_evt_t *pevt)
{
    uint8_t i,j;
    
    switch (pevt->evt)
    {
        case SPI_RX_DATA_S:
            for(i=0;i<pevt->len;i++) 
            {
                slaveRxBuf[slaveRxLen+i] = pevt->data[i];
            }
            slaveRxLen += pevt->len;
            
            for(j=0;j<slaveRxLen;j++)
            {
//                LOG("%c ",slaveRxBuf[i]);
                if(slaveRxBuf[j] == '\0')   //clear receiving interference
                {
                    slaveRxLen = 0;
                }
            }
    
            if(slaveRxLen >=6 && osal_memcmp(slaveRxBuf, "RLEN", osal_strlen("RLEN"))) {
                slaveTxLen = str2int((char *)(slaveRxBuf + (osal_strlen("RLEN"))));
                LOG("\r\nRx:%d\r\n",slaveTxLen);
                HalSpiSlaveTxPrepare(AP_SPI0, (uint8_t *)slaveTxBuf, slaveTxLen);
                slaveRxLen = 0;
                osal_memset(slaveRxBuf,0,sizeof(slaveRxBuf));
                slaveRxEnable = 0;
            }
            else if(slaveRxLen >=6 && osal_memcmp(slaveRxBuf, "SLEN", osal_strlen("SLEN"))) {
                slaveRxLen = str2int((char *)(slaveRxBuf + (osal_strlen("SLEN"))));
                osal_memset(slaveRxBuf,0,sizeof(slaveRxBuf));
                LOG("\r\nTx:%d\r\n",slaveRxLen);
                slaveRxNum = slaveRxLen;
                slaveRxLen = 0;
                slaveRxEnable = 1;
            }
            else if(slaveRxEnable){
                if(slaveRxLen >= slaveRxNum){
                    LOG("\r\nspi slave :dataLen:%d,data:%s\r\n",slaveRxLen,slaveRxBuf);
                    slaveRxEnable = 0;
                    slaveRxLen = 0;
                    osal_memset(slaveRxBuf,0,sizeof(slaveRxBuf));
                }
            }
//            else if(slaveRxLen >7) {
//                slaveRxLen = 0;
//                osal_memset(slaveRxBuf,0,sizeof(slaveRxBuf));
////                for(i=0;i<pevt->len;i++) {
////                    LOG("%x ", pevt->data[i]);
////                }
//            }
//            LOG("%d", slaveRxLen);
            break;
        default:
            break;
    }
}

/**
* @fn void sample_spi_master_start(void)
* @brief spi master sample function
* @param NONE
* @return NONE.
*/
uint8_t  txBuffer[80] = {0};
uint8_t  rxBuffer[40] = {0};
void sample_spi_master_start(void)
{
    static uint8_t step = 0;
    char   *txBuf = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ+-*@";
    
    switch(step%4){
        case 0:{
            osal_memset(txBuffer, 0, sizeof(txBuffer));
            sprintf((char*)txBuffer, "SLEN%d",40);
            HalSpiMasterTransfer(AP_SPI0, SPI_TXD, (uint8_t *)txBuffer, NULL, osal_strlen((char*)txBuffer));
            LOG("send slen:%d\r\n", osal_strlen((char*)txBuffer));
		}break;
		
        case 1:{
            HalSpiMasterTransfer(AP_SPI0, SPI_TXD, (uint8_t *)txBuf, NULL, 40);
            LOG("spi master send ok----------\n");
            LOG("send data\r\n");
        }break;

        case 2:{
            osal_memset(rxBuffer, 0, sizeof(rxBuffer));
            osal_memset(txBuffer, 0, sizeof(txBuffer));
            sprintf((char*)txBuffer, "RLEN%d",32);
            HalSpiMasterTransfer(AP_SPI0, SPI_TXD, (uint8_t *)txBuffer, NULL, osal_strlen((char*)txBuffer));
            LOG("send rlen\r\n");
		}break;
		
        case 3:{
//            HalSpiDmaSet(SPI0, false, false);
            HalSpiMasterTransfer(AP_SPI0, SPI_TRXD, NULL, rxBuffer, 32);
			while(HalSpiGetTransmitState(SPI0));
            LOG("%s(%d):%s\n", __func__, __LINE__, rxBuffer);
        }break;
    }
    step++;
}

uint8_t buf_send[0x1000];
/**
 * @fn      void HalPeripheral_Init(uint8 task_id)
 * @brief   Peripheral initialization
 * @param   task_id
 * @return  none
 */
void HalPeripheral_Init(uint8 task_id)
{
	uint8_t retval = ERR_NONE;
	spi_Cfg_t cfg;
	
	Hal_TaskID = task_id;

#ifdef SPI_MASTER
	HalDMAInit();
    retval = HalDMAInitChannel(dma_cfg);
    if(retval != ERR_NONE)
    {
        LOG("dma init err!\r\n");
    }
	
	cfg.ssn_pin = P31;
	cfg.sclk_pin = P32;
	cfg.MISO = P33;
	cfg.MOSI = P34;
	cfg.baudrate = 400000;
    cfg.spi_tmod = SPI_TRXD;
	cfg.spi_scmod = SPI_MODE0;
	cfg.spi_dfsmod = SPI_1BYTE;
    cfg.dma_rx_enable = false;
    cfg.dma_tx_enable = false;
	cfg.int_mode = false;
	cfg.evt_handler = NULL;
	cfg.force_cs = false;
    cfg.is_slave = false;
	retval = HalSpiMasterConfig(AP_SPI0, &cfg);
	if(retval != ERR_NONE)
    {
        LOG("spi init err!\r\n");
    }
    LOG("SPI Master Init\r\n");
    osal_start_timerEx(Hal_TaskID, USR_SPI_MASTER_TEST, 1002);
#else
    cfg.ssn_pin = P31;
	cfg.sclk_pin = P32;
	cfg.MISO = P33;
	cfg.MOSI = P34;
    cfg.spi_tmod = SPI_TRXD;
	cfg.spi_scmod = SPI_MODE0;
	cfg.spi_dfsmod = SPI_1BYTE;
    cfg.dma_rx_enable = false;
    cfg.dma_tx_enable = false;
	cfg.int_mode = true;
	cfg.evt_handler = UserSpiHandle;
	cfg.force_cs = false;
    cfg.is_slave = true;
    retval = HalSpiSlaveConfig(AP_SPI0, &cfg);
    
	LOG("SPI Slave Init\r\n");
#endif
	
	for(uint16_t i=0; i<0x1000; i++)
	{
		buf_send[i] = i&0xFF;
	}
}

/**
 * @fn      uint16 HalPeripheral_ProcessEvent( uint8 task_id, uint16 events )
 * @brief   Peripheral event process
 * @param   task_id
 * @param	events
 * @return  none
 */
uint16 HalPeripheral_ProcessEvent( uint8 task_id, uint16 events )
{
	if(task_id != Hal_TaskID)
    {
		return 0;
	}
	
	if( events & USR_SPI_MASTER_TEST )
    {
		static uint8_t testNum = 0;
        
//		HalSpiDmaSet(SPI0, false, false);
//        HalSpiMasterTransfer(&hal_spi, SPI_TXD, NULL, buf_send, 0, 4);
//        HalSpiMasterTransfer(&hal_spi, SPI_TXD, buf_send, NULL, 0x7ff, 0);
        sample_spi_master_start();
        LOG("USR_SPI_MASTER_TEST\r\n");
        if(++testNum < 8)
        {
            VOID osal_start_timerEx( Hal_TaskID, USR_SPI_MASTER_TEST, 1002);
        }
        return ( events ^ USR_SPI_MASTER_TEST );
    }
	
	if( events & USR_SPI_SLAVE_TEST )
	{
		LOG("USR_SPI_SLAVE_TEST\r\n");
        
		return ( events ^ USR_SPI_SLAVE_TEST );
	}
	
    return 0;
}

/*********************************************************************
*********************************************************************/
